package auth

import (
	"errors"
	"github.com/astaxie/beego/orm"
	"time"
)

var (
	UsernameAndEmailEmptyError = errors.New("username or email cannot be empty at the same time")
	PasswordError              = errors.New("password error")
	UserDoesNotExist           = errors.New("user does not exist")
)

type User struct {
	Id                int
	Username          string    `orm:"size(64);unique"`
	Password          string    `orm:"size(64)"`
	Email             string    `orm:"size(64);unique"`
	Telephone         string    `orm:"size(15);index"`
	Role              string    `orm:"size(32);"`
	Status            int       // 0 正常 1 需要修改密码 2 需要重新登录 3 异地登录 99 关闭
	PasswordExpiredAt time.Time `orm:"type(datetime)"` // 密码过期时间
	CreateAt          time.Time `orm:"type(datetime)"`
}

func (o *User) TableName() string {
	return "auth_users"
}

func (o *User) NickName() string {
	if o.Role == "admin" {
		return "管理员"
	} else {
		return "游客"
	}
}
func ChangePassword(username, password string) error {
	user := User{}
	err := orm.NewOrm().QueryTable(new(User)).Filter("username", username).One(&user)
	if err != nil {
		if err == orm.ErrNoRows {
			return UserDoesNotExist
		}
		return err
	}
	user.Password = password
	_, err = orm.NewOrm().Update(&user)
	return err
}

func GetUserFromId(id int) (User, error) {
	user := User{Id: id}
	err := orm.NewOrm().Read(&user)
	if err != nil {
		if err == orm.ErrNoRows {
			return user, UserDoesNotExist
		}
		return user, err
	}
	return user, nil
}

func Authentication(username, email, password string) (user *User, err error) {
	user = &User{}
	if username == "" && email != "" {
		return nil, UsernameAndEmailEmptyError
	}
	if username != "" {
		user.Username = username
		err = orm.NewOrm().Read(user, "username")
	} else {
		user.Email = email
		err = orm.NewOrm().Read(user, "email")
	}
	if err != nil {
		if err == orm.ErrNoRows {
			return nil, UserDoesNotExist
		}
		return
	}

	if user.Password != password {
		return nil, PasswordError
	}
	return
}

func CreateAdminUserAccount(username, password, email string) error {
	expiredAt := time.Date(2099, 12, 31, 23, 59, 59, 59, time.Local)
	user := User{Username: username, Password: password, Email: email, CreateAt: time.Now(), PasswordExpiredAt: expiredAt, Role: "admin"}
	_, err := orm.NewOrm().Insert(&user)
	return err
}

func CreateUserAccount(username, password, email string) error {
	expiredAt := time.Date(2099, 12, 31, 23, 59, 59, 59, time.Local)
	user := User{Username: username, Password: password, Email: email, CreateAt: time.Now(), PasswordExpiredAt: expiredAt, Role: "user"}
	_, err := orm.NewOrm().Insert(&user)
	return err
}

func GetUsersPaginator(limit, page int) ([]User, int64, error) {
	if limit == 0 {
		limit = 10
	}
	if page == 0 {
		page = 1
	}
	var all []User
	total, err := orm.NewOrm().QueryTable(new(User)).Count()
	if err != nil {
		return nil, 0, err
	}
	_, err = orm.NewOrm().QueryTable(new(User)).Offset((page - 1) * limit).Limit(limit).All(&all)
	return all, total, err
}
